package com.tvb.comm.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;




/**
 * @author stan
 *
 */
public class HTTPInterfaceUtil {
	static Log log = LogFactory.getLog(HTTPInterfaceUtil.class.getName());

	/**
	 * 出现网络中断，重复执行的次数,对应的value 为int类型
	 */
	public static final byte RETRY_HANDLER_COUNT_KEY = 0x01;
	/**
	 * 代理host 字符形式
	 */
	public static final byte PROXY_HOST_KEY = 0x02;
	/**
	 * 代理post 对应的value为int类型
	 */
	public static final byte PROXY_PORT_KEY = 0x03;
	/**
	 * 代理账号  字符形式
	 */
	public static final byte PROXY_USERNAME_KEY = 0x04;
	/**
	 * 代理密码  字符形式
	 */
	public static final byte PROXY_PASSWORD_KEY = 0x05;
	
	/**
	 * 请求方式
	 */
	public static final byte REQUEST_METHOD_KEY = 0x06; 
	
	/**
	 * get
	 */
	public static final byte REQUEST_GET = 0x07; 
	
	/**
	 * post
	 */
	public static final byte REQUEST_POST = 0x08;
	
	/**
	 * data post请求设置的form数据
	 */
	public static final byte REQUEST_DATA = 0x09;
	
	/**
	 * 请求超时时间
	 */
	public static final byte REQUEST_TIMEOUT = 0x10;
	/**
	 * 获取url 返回内容
	 * @param url 
	 * @param params
	 * ***************************************</br>
	 * <body>
	 * 	params 通过内部静态常量来设置requst的请求参数</br>
	 * 	例子： 设置请求默认的恢复策略，在发生异常时候将自动重试</br>
	 * params.put(HTTPInterfaceUtil.RETRY_HANDLER_COUNT_KEY,"2")//自动重试两次，默认设置三次</br>
	 * params.put(HTTPInterfaceUtil.REQUEST_METHOD_KEY,HTTPInterfaceUtil.REQUEST_POST);//设置为post请求
	 * </body>
	 * @return
	 * @throws IOException 
	 * @throws HttpException 
	 */
	public static String request(String url, Map<Byte, Object> params) throws HttpException, IOException {
		String reult = "";
		HttpClient client = new HttpClient();
		HttpMethod method = null;
		method = setRequestMethod(url,client, params);
		try {
			int statusCode = client.executeMethod(method);
			if (statusCode == HttpStatus.SC_OK) {
				reult = getResponseBodyAsStream(method);
			} else {
				log.info(("HostCode 加载失败 状态: " + method.getStatusLine()));
			}
		} finally {
			method.releaseConnection();
		}
		return reult;
	}

	
	/**
	 * 设置请求参数
	 * @param client
	 * @param params
	 * @return
	 */
	private static HttpMethod setRequestMethod(String url,HttpClient client,Map<Byte, Object> params){
		HttpMethod method = null;
		if(params != null){
			Integer count =(Integer)params.get(RETRY_HANDLER_COUNT_KEY);
			String host = (String) params.get(PROXY_HOST_KEY);
			Integer port = (Integer) params.get(PROXY_PORT_KEY);
			String userName = (String) params.get(PROXY_USERNAME_KEY);
			String password = (String) params.get(PROXY_PASSWORD_KEY);
			Byte requstMethod = (Byte) params.get(REQUEST_METHOD_KEY);
			Integer timeOut =(Integer)params.get(REQUEST_TIMEOUT);
			log.info(url);
			if(requstMethod==null)method = new GetMethod(url);
			else if(requstMethod == REQUEST_POST)method = new PostMethod(url);
			else if(requstMethod == REQUEST_GET)method = new GetMethod(url);
			if(count != null){
				method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
						new DefaultHttpMethodRetryHandler(count, false));
			}
			if(timeOut != null){
				method.getParams().setSoTimeout(timeOut);
			}
			if(StringUtil.isNoBlank(host) && port != null){
				client.getHostConfiguration().setProxy(host, port);
			}
			if(StringUtil.isNoBlank(userName) && StringUtil.isNoBlank(password)){
				Credentials credentials = new UsernamePasswordCredentials(
						userName, password);
				client.getState().setCredentials(AuthScope.ANY, credentials);
			}	
		}else{
			method = new GetMethod();
		}
		return method;
	}
	/**
	 * 获取请求放回的数据
	 * 
	 * @param method
	 * @return
	 * @throws IOException
	 */
	private static String getResponseBodyAsStream(HttpMethod method)
			throws IOException {
		String reult = "";
		BufferedInputStream bis = new BufferedInputStream(
				method.getResponseBodyAsStream());
		byte[] bytes = new byte[1024];
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		int count = 0;
		while ((count = bis.read(bytes)) != -1) {
			bos.write(bytes, 0, count);
		}
		byte[] strByte = bos.toByteArray();
		reult = new String(strByte, 0, strByte.length,"UTF-8");
		bos.close();
		bis.close();
		return reult;
	}
}
